home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / polyview / polyvw31.lha / Polyview3.1 / new / pvrender.c < prev    next >
C/C++ Source or Header  |  1993-08-13  |  36KB  |  1,218 lines

  1. /*****************************************************************************
  2.  * NCSA Polyview 3.1                                                         *
  3.  *                                                                           *
  4.  * Version 3.1 changes and additions by Gilles Bourhis.                      *
  5.  * Version 3 changes and additions by Marc Andreessen.                       *
  6.  * Version 2 by Brian Calvert.                                               *
  7.  *                                                                           *
  8.  * Software Development Group                                                *
  9.  * National Center for Supercomputing Applications                           *
  10.  * University of Illinois at Urbana-Champaign                                *
  11.  *                                                                           *
  12.  * This is BETA release software.  As such it may contain software bugs and  *
  13.  * exhibit inconsistencies.                                                  *
  14.  *                                                                           *
  15.  * Please send bug reports to polyview@ncsa.uiuc.edu.                        *
  16.  *                                                                           *
  17.  * Copyright (c) 1992 The Board of Trustees of the University of Illinois.   *
  18.  *                                                                           *
  19.  * Permission to use, copy, and modify this software and its                 *
  20.  * documentation for educational, research, and non-profit purposes is       *
  21.  * hereby granted, provided that the above copyright notice, the original    *
  22.  * authors names, and this permission notice appear in all such copies.      *
  23.  * Any distribution of this software requires the explicit and written       *
  24.  * authorization of the authors.                                             *
  25.  *                                                                           *
  26.  * The University of Illinois makes no representations about the             *
  27.  * suitability of this software for any purpose.  It is provided "as is"     *
  28.  * without warranty of any kind.                                             *
  29.  *****************************************************************************/
  30.  
  31. /* $Id: pvrender.c,v 1.2 93/08/13 13:18:23 gbourhis Exp $ */
  32.  
  33. #ifdef RCSLOG
  34. $Log:    pvrender.c,v $
  35.  * Revision 1.2  93/08/13  13:18:23  gbourhis
  36.  * correct viewpoint.
  37.  * 
  38.  * Revision 1.1  92/09/18  10:55:26  marca
  39.  * Initial revision
  40.  * 
  41. #endif
  42.   
  43. #include "pv.h"
  44.  
  45. #define PI 3.14159265
  46.  
  47. /* Start of RenderMan-specific code. */
  48. #ifdef RENDERMAN
  49.   
  50. /* Choose method for RenderMan interface. */
  51. /* #define DUMP_CFILE */
  52. #define DIRECT_RENDERMAN
  53.  
  54.  
  55. #ifdef DIRECT_RENDERMAN
  56.  
  57. /* ------------------------------------------------------------------------ */
  58. /* ------------------------ DIRECT RENDERMAN CODE ------------------------- */
  59. /* ------------------------------------------------------------------------ */
  60.  
  61. #include <ri.h>
  62.  
  63. static RtColor rc[256];
  64. static RtColor rc_default = {0.8, 0.8, 0.8};
  65. static RtPoint rp[8];
  66.  
  67. static int num_vertices = 0;
  68.  
  69. static void rm_bgnpolygon (void)
  70. {
  71.   num_vertices = 0;
  72.   return;
  73. }
  74.  
  75. static void rm_v3f (float *vv)
  76. {
  77.   /* Copy the vertex. */
  78.   rp[num_vertices][0] = vv[0];
  79.   rp[num_vertices][1] = vv[1];
  80.   rp[num_vertices][2] = vv[2];
  81.  
  82.   /* Increment the count. */
  83.   num_vertices++;
  84.  
  85.   return;
  86. }
  87.  
  88. static void rm_endpolygon (void)
  89. {
  90.   RiPolygon( (RtInt)num_vertices, RI_P, (RtPointer)rp, RI_NULL );
  91.   return;
  92. }
  93.  
  94. static void rm_palettecpack (int c)
  95. {
  96.   /* Suck the color out of preloaded array of RtColor's. */
  97.   RiColor(rc[c]);
  98. }
  99.  
  100.  
  101.  
  102. /* ------------------------------------------------------------------------ */
  103. /* ----------------------------- SPHERE SHIT ------------------------------ */
  104. /* ------------------------------------------------------------------------ */
  105.  
  106. static float sphere_size;
  107.  
  108. /* 1 if vertices should be drawn as cubes. */
  109. static int sphere_cubes;
  110.  
  111.  
  112. #define L -.5       /* For x: left side     */
  113. #define RIGHT  .5       /* For x: right side    */
  114. #define D -.5       /* For y: down side     */
  115. #define U  .5       /* For y: upper side    */
  116. #define F  .5       /* For z: far side      */
  117. #define N -.5       /* For z: near side     */
  118.  
  119. /* UnitCube(): define a cube in the graphics environment */
  120. static void UnitCube (void)
  121. {
  122.   static RtPoint Cube[6][4] = {
  123.     { {L,D,F},  {L,D,N},  {RIGHT,D,N},  {RIGHT,D,F} },   /* Bottom face  */
  124.     { {L,D,F},  {L,U,F},  {L,U,N},  {L,D,N} },           /* Left face    */
  125.     { {RIGHT,U,N},  {L,U,N},  {L,U,F},  {RIGHT,U,F} },   /* Top  face    */
  126.     { {RIGHT,U,N},  {RIGHT,U,F},  {RIGHT,D,F},  {RIGHT,D,N} },   
  127.                                                          /* Right face   */
  128.     { {RIGHT,D,F},  {RIGHT,U,F},  {L,U,F},  {L,D,F} },   /* Far face     */
  129.     { {L,U,N},  {RIGHT,U,N},  {RIGHT,D,N},  {L,D,N} }    /* Near face    */
  130.   };
  131.   int i;
  132.   for( i = 0; i < 6; i++)  /* Declare the cube  */
  133.     RiPolygon( (RtInt) 4, RI_P, (RtPointer) Cube[i], RI_NULL);
  134. }
  135.  
  136.  
  137. static void rm_sphdraw (float *vv)
  138. {
  139.   if (sphere_cubes)
  140.     {
  141.       RiTransformBegin ();
  142.       {
  143.         RiTranslate (vv[0], vv[1], vv[2]);
  144.         RiScale (sphere_size*2.0, sphere_size*2.0, sphere_size*2.0);
  145.         UnitCube ();
  146.       }
  147.       RiTransformEnd ();
  148.     }
  149.   else
  150.     {
  151.       RiTransformBegin();
  152.       {
  153.         RiTranslate ((RtFloat)vv[0], (RtFloat)vv[1], (RtFloat)vv[2]);
  154.         RiSphere (sphere_size, -sphere_size, sphere_size, 360.0, RI_NULL);
  155.       }
  156.       RiTransformEnd();
  157.     }
  158.  
  159.   return;
  160. }
  161.  
  162.  
  163. /* ------------------------------------------------------------------------ */
  164. /* ------------------------------ LINE SHIT ------------------------------- */
  165. /* ------------------------------------------------------------------------ */
  166.  
  167. /* Keep a static array of vertices and a count of the number
  168.    of vertices in the array. */
  169. static float line_vv[20][3];
  170. static int line_vv_count = 0;
  171.  
  172. static int line_cc[20];
  173. static int line_cc_used = 0;
  174.  
  175. /* Static width of lines drawn as cylinders. */
  176. static float line_width = 0.1;
  177.  
  178. /* This should be a window-local variable or something. */
  179. static int cap_cylinders = 0;
  180.  
  181.  
  182. static void DoCylinder (float line_width,
  183.                         float x1, float y1, float z1,
  184.                         float x2, float y2, float z2)
  185. {
  186.   float offset[3], len, xang, yang;
  187.  
  188.   if (FEQ(y1, y2)) 
  189.     xang = 3.14159265 * 0.5;
  190.   else 
  191.     xang = atanf (sqrtf ((x2-x1)*(x2-x1)+(z2-z1)*(z2-z1))/(y2-y1));
  192.   yang = atan2f ((x2-x1),(z2-z1));
  193. #if 0
  194.   if (yang != yang)
  195.     return;
  196. #endif
  197.   xang *= 180.0 / 3.14159265;
  198.   yang *= 180.0 / 3.14159265;
  199.   
  200.   offset[0] = (x1+x2)*0.5;
  201.   offset[1] = (y1+y2)*0.5;
  202.   offset[2] = (z1+z2)*0.5;
  203.   len = sqrtf( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1) );
  204.  
  205.   RiTransformBegin ();
  206.   {
  207.     RiTranslate( offset[0], offset[1], offset[2] );
  208.     RiRotate ( yang, 0.0, 1.0, 0.0 );
  209.     RiRotate ( xang, 1.0, 0.0, 0.0 );
  210.     RiScale ( 1.0, len, 1.0 );
  211.  
  212.     RiRotate ( 90.0, 1.0, 0.0, 0.0 );
  213.     RiCylinder (line_width, -0.5, 0.5, 360.0, RI_NULL);
  214.   }
  215.   RiTransformEnd ();
  216.   
  217.   return;
  218. }
  219.  
  220.  
  221.  
  222. static void rm_linepalettecpack (int c)
  223. {
  224.   /* Save this color index with the current vertex. */
  225.   line_cc[line_vv_count] = c;
  226.  
  227.   /* Note that we are using colors for this line. */
  228.   line_cc_used = 1;
  229. }
  230.  
  231. static void rm_bgnclosedline (void)
  232. {
  233.   /* Starting a new line. */
  234.   line_vv_count = 0;
  235.   
  236.   /* Haven't used any colors yet. */
  237.   line_cc_used = 0;
  238. }
  239.  
  240. static void rm_endclosedline (void)
  241. {
  242.   int i;
  243.  
  244.   /* If we have one or fewer vertices, punt. */
  245.   if (line_vv_count < 2)
  246.     goto done;
  247.  
  248.   /* For each vertex up to the second-to-last, make
  249.      a cylinder with the vertex and its successor. */
  250.   for (i = 0; i < line_vv_count - 1; i++)
  251.     {
  252.       if (line_cc_used)
  253.         RiColor (rc[line_cc[i]]);
  254.       else
  255.         RiColor (rc_default);
  256.  
  257.       DoCylinder 
  258.         (/* radius */ line_width,
  259.          /* end 1  */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
  260.          /* end 2  */ line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2]);
  261.  
  262. #if 0      
  263.       if (cap_cylinders)
  264.         {
  265.           fprintf (rayfp, "  disc\n");
  266.           if (line_cc_used)
  267.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  268.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  269.                    "line_width",
  270.                    line_vv[i][0], line_vv[i][1], line_vv[i][2],
  271.                    line_vv[i][0] - line_vv[i+1][0],
  272.                    line_vv[i][1] - line_vv[i+1][1],
  273.                    line_vv[i][2] - line_vv[i+1][2]);
  274.           fprintf (rayfp, "  disc\n");
  275.           if (line_cc_used)
  276.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  277.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  278.                    "line_width",
  279.                    line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2],
  280.                    line_vv[i+1][0] - line_vv[i][0],
  281.                    line_vv[i+1][1] - line_vv[i][1],
  282.                    line_vv[i+1][2] - line_vv[i][2]);
  283.         }
  284. #endif
  285.     }
  286.  
  287.  
  288.   /* If there's more than 2 vertices, close the line. */
  289.   if (line_vv_count > 2)
  290.     {
  291.       i = line_vv_count - 1;
  292.       
  293.       if (line_cc_used)
  294.         RiColor (rc[line_cc[i]]);
  295.       else
  296.         RiColor (rc_default);
  297.       
  298.       DoCylinder 
  299.         (/* radius */ line_width,
  300.          /* end 1  */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
  301.          /* end 2  */ line_vv[0][0], line_vv[0][1], line_vv[0][2]);
  302.       
  303. #if 0      
  304.       if (cap_cylinders)
  305.         {
  306.           fprintf (rayfp, "  disc\n");
  307.           if (line_cc_used)
  308.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  309.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  310.                    "line_width",
  311.                    line_vv[i][0], line_vv[i][1], line_vv[i][2],
  312.                    line_vv[i][0] - line_vv[0][0],
  313.                    line_vv[i][1] - line_vv[0][1],
  314.                    line_vv[i][2] - line_vv[0][2]);
  315.           fprintf (rayfp, "  disc\n");
  316.           if (line_cc_used)
  317.             fprintf (rayfp, "    pal%1d\n", line_cc[i]);
  318.           fprintf (rayfp, "    %s\n    %f %f %f\n    %f %f %f\n",
  319.                    "line_width",
  320.                    line_vv[0][0], line_vv[0][1], line_vv[0][2],
  321.                    line_vv[0][0] - line_vv[i][0],
  322.                    line_vv[0][1] - line_vv[i][1],
  323.                    line_vv[0][2] - line_vv[i][2]);
  324.         }
  325. #endif
  326.     }
  327.   
  328.  done:
  329.   line_vv_count = 0;
  330.   return;
  331. }
  332.  
  333.  
  334. static void rm_linev3f (float *vv)
  335. {
  336.   /* Store this vertex. */
  337.   line_vv[line_vv_count][0] = vv[0];
  338.   line_vv[line_vv_count][1] = vv[1];
  339.   line_vv[line_vv_count][2] = vv[2];
  340.  
  341.   /* Increment the count. */
  342.   line_vv_count++;
  343.  
  344.   return;
  345. }
  346.  
  347.  
  348.  
  349. /* ------------------------------------------------------------------------ */
  350. /* --------------------------- rm_draw_vertices --------------------------- */
  351. /* ------------------------------------------------------------------------ */
  352.  
  353. static int rm_draw_vertices (state_t *state, window_t *win, object_t *obj, 
  354.                            objinfo_t *info)
  355. {
  356.   long    count;
  357.   
  358.   Vdata_t **vdata;
  359.   Vdata_t *vcolor_v;
  360.   Vdata_t *pcoord_v;
  361.   
  362.   float    (*pcoord)[DIMS];
  363.   int *vcolor;
  364.   char *picked;
  365.  
  366.   int single_color;
  367.   
  368.   /* Get pointers to the pertinent data sets */
  369.   vdata = obj->u.obj.vdata;
  370.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  371.   if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  372.     return ST_OKAY;
  373.  
  374.   /* Set up the consolidated coordinate array pointer. */
  375.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  376.   count = pcoord_v->stats[0].rec_count;
  377.   assert (pcoord_v->stats[0].type == PVFLOAT);
  378.  
  379.   if (FEQ(win->sphere_size, 0.0))
  380.     sphere_size = win->max_width * 0.01;
  381.   else
  382.     sphere_size = win->sphere_size;
  383.  
  384.   sphere_cubes = (win->sphere_depth == 1);
  385.  
  386.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  387.     {
  388.       /* No color information.  Use foreground and draw the */
  389.       /* appropriate shapes. */
  390.       while (count > 0) 
  391.         {
  392.           { /* not selected */
  393.             float params[4];
  394.             
  395.             params[0] = (*pcoord)[0];
  396.             params[1] = (*pcoord)[1];
  397.             params[2] = (*pcoord)[2];
  398.             params[3] = win->sphere_size;
  399.             
  400.             rm_sphdraw (params);
  401.           }
  402.           
  403.           /* Move to the next x, y, z set and decrement the */
  404.           /* count. */
  405.           pcoord++;
  406.           count--;
  407.         }
  408.     }
  409.   else 
  410.     {
  411.       /* Set pointers to the actual data and the size of the data */
  412.       /* sets. */
  413.       assert (vcolor_v->stats[0].type == PVINTEGER);
  414.       
  415.       /* There is color information.  Get it and use it to draw the */
  416.       /* appropriate shapes. */
  417.       vcolor = (int *) vcolor_v->data;
  418.       
  419.       while (count > 0) 
  420.         {
  421.           { /* not selected */
  422.             float params[4];
  423.             
  424.             rm_palettecpack(*vcolor);
  425.             
  426.             params[0] = (*pcoord)[0];
  427.             params[1] = (*pcoord)[1];
  428.             params[2] = (*pcoord)[2];
  429.             params[3] = win->sphere_size;
  430.             
  431.             rm_sphdraw (params);      
  432.           }
  433.           /* Move to the next x, y, z set, color entry, and */
  434.           /* decrement the count. */
  435.           pcoord++;
  436.           vcolor++;
  437.           count--;
  438.         }
  439.     }
  440.  
  441.   return ST_OKAY;
  442. }
  443.  
  444.  
  445. /* ------------------------------------------------------------------------ */
  446. /* ------------------------------------------------------------------------ */
  447. /* ------------------------------------------------------------------------ */
  448.  
  449.  
  450. static int rm_draw_edges (state_t *state, window_t *win, object_t *obj, 
  451.                            objinfo_t *info)
  452. {
  453.   long count;
  454.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  455.   float (*pcoord)[DIMS];
  456.   int *vcolor, *connect;
  457.   char *picked;
  458.   int i, nvert, vertex;
  459.  
  460.   /* Set the width of the cylinders. */
  461.   line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
  462.  
  463.   /* Get pointers to the pertinent data sets. */
  464.   vdata = obj->u.obj.vdata;
  465.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  466.   if ((connect_v = get_vdata(state, vdata[CONNECT])) == NULL) 
  467.     if ((connect_v = get_vdata(state, vdata[MCONNECT])) == NULL) 
  468.       {
  469.         rm_draw_vertices(state, win, obj, info);
  470.         return ST_OKAY;
  471.       }
  472.   if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  473.     return ST_OKAY;
  474.   
  475.   /* Collect connectivity information for drawing. */
  476.   connect = (int *) connect_v->data;
  477.   count = connect_v->stats[0].rec_count;
  478.   nvert = connect_v->stats[0].rec_size;
  479.   
  480.   /* Set up the consolidated coordinate array pointer. */
  481.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  482.   assert (pcoord_v->stats[0].type == PVFLOAT);
  483.   
  484.   /* If there is no vertex color information, draw without it */
  485.   /* (use the FOREGROUND color).  Otherwise, grab the color array. */
  486.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  487.     {
  488.       /* No color information.  Use foreground and draw the */
  489.       /* appropriate shapes. */
  490.       while (count > 0) 
  491.         {
  492.           rm_bgnclosedline();
  493.           
  494.           for (i = nvert; i > 0; i--) 
  495.             {
  496.               if ( (vertex = *(connect++)-1) == -1) 
  497.                 {
  498.                   connect += i-1;
  499.                   break;
  500.                 }
  501.               rm_linev3f(pcoord[vertex]);
  502.             }
  503.           
  504.           rm_endclosedline();
  505.           
  506.           count--;
  507.         }
  508.     }
  509.   else 
  510.     {
  511.       /* Set pointers to the actual data and the size of the data */
  512.       /* sets. */
  513.       assert (vcolor_v->stats[0].type == PVINTEGER);
  514.       
  515.       /* There is color information.  Get it and use it to draw the */
  516.       /* appropriate shapes. */
  517.       vcolor = (int *) vcolor_v->data;
  518.       while (count > 0) 
  519.         {
  520.           rm_bgnclosedline();
  521.           
  522.           for (i = nvert; i > 0; i--) 
  523.             {
  524.               if ( (vertex = *(connect++)-1) == -1) 
  525.                 {
  526.                   connect += i-1;
  527.                   break;
  528.                 }
  529.  
  530.               rm_linepalettecpack(vcolor[vertex]);
  531.               rm_linev3f(pcoord[vertex]);
  532.             }
  533.           
  534.           rm_endclosedline();
  535.           
  536.           count--;
  537.         }
  538.     }
  539.  
  540.   return ST_OKAY;
  541. }
  542.  
  543.  
  544.  
  545. /* ------------------------------------------------------------------------ */
  546. /* ---------------------------- rm_draw_faces ----------------------------- */
  547. /* ------------------------------------------------------------------------ */
  548.  
  549. static int rm_draw_faces (state_t *state, window_t *win, object_t *obj, 
  550.                           objinfo_t *info)
  551. {
  552.   long count;
  553.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  554.   float    (*pcoord)[DIMS];
  555.   int *vcolor, *connect;
  556.   char *picked;
  557.   int i, nvert, vertex, single_color;
  558.   
  559.   /* Get pointers to the pertinent data sets */
  560.   vdata = obj->u.obj.vdata;
  561.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  562.   if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
  563.     if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
  564.       return rm_draw_vertices(state, win, obj, info);
  565.   
  566.   /* If the plist does not describe polygons, draw edges. */
  567.   if (connect_v->stats[0].rec_size < 3)
  568.     return rm_draw_edges(state, win, obj, info);
  569.   
  570.   if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  571.     return ST_OKAY;
  572.   
  573.   /* Collect connectivity information for drawing. */
  574.   connect = (int *) connect_v->data;
  575.   count = connect_v->stats[0].rec_count;
  576.   nvert = connect_v->stats[0].rec_size;
  577.   
  578.   /* Set up the consolidated coordinate array pointer. */
  579.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  580.   assert (pcoord_v->stats[0].type == PVFLOAT);
  581.   
  582.   /* If there is no vertex color information, draw without it */
  583.   /* (use the FOREGROUND color).  Otherwise, grab the color array. */
  584.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  585.     {
  586.       while (count > 0) 
  587.         {
  588.           rm_bgnpolygon();
  589.           for (i = nvert; i > 0; i--) 
  590.             {
  591.               if ( (vertex = *(connect++)-1) == -1) 
  592.                 {
  593.                   connect += i-1;
  594.                   break;
  595.                 }
  596.               rm_v3f(pcoord[vertex]);
  597.             }
  598.           rm_endpolygon();
  599.           
  600.           count--;
  601.         }
  602.     }
  603.   else 
  604.     {
  605.       /* Set pointers to the actual data and the size of the data */
  606.       /* sets. */
  607.       assert (vcolor_v->stats[0].type == PVINTEGER);
  608.       
  609.       /* There is color information.  Get it and use it to draw the */
  610.       /* appropriate shapes. */
  611.       vcolor = (int *) vcolor_v->data;
  612.  
  613.       while (count > 0) 
  614.         {
  615.           rm_bgnpolygon();
  616.           for (i = nvert; i > 0; i--) 
  617.             {
  618.               if ((vertex = *(connect++)-1) == -1) 
  619.                 {
  620.                   connect += i-1;
  621.                   break;
  622.                 }
  623.               
  624.               if (i == nvert)
  625.                 rm_palettecpack (vcolor[vertex]);
  626.  
  627.               rm_v3f(pcoord[vertex]);
  628.             }
  629.           rm_endpolygon();
  630.           
  631.           count--;
  632.         }
  633.     }
  634.   
  635.   return ST_OKAY;
  636. }
  637.  
  638.  
  639.  
  640. /* ------------------------------------------------------------------------ */
  641. /* ------------------------ rm_draw_outlined_faces ------------------------ */
  642. /* ------------------------------------------------------------------------ */
  643.  
  644. static int rm_draw_outlined_faces(state_t *state, window_t *win, 
  645.                                    object_t *obj,
  646.                                    objinfo_t *info)
  647. {
  648.   long count;
  649.   
  650.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  651.   
  652.   float (*pcoord)[DIMS];
  653.   float pcoord_outline[DIMS];
  654.   int *vcolor, *connect, *oconnect;
  655.   char *picked;
  656.   int i, j, nvert, vertex, single_color;
  657.  
  658.   /* Set the width of the cylinders. */
  659.   line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
  660.  
  661.   /* Get pointers to the pertinent data sets */
  662.   vdata = obj->u.obj.vdata;
  663.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  664.   if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL) 
  665.     if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL) 
  666.       return rm_draw_vertices(state, win, obj, info);
  667.  
  668.   /* If the plist does not describe polygons, draw edges. */
  669.   if (connect_v->stats[0].rec_size < 3)
  670.     return rm_draw_edges(state, win, obj, info);
  671.   
  672.   if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  673.     return ST_OKAY;
  674.   
  675.   /* Collect connectivity information for drawing. */
  676.   oconnect = connect = (int *) connect_v->data;
  677.   count = connect_v->stats[0].rec_count;
  678.   nvert = connect_v->stats[0].rec_size;
  679.   
  680.   /* Set up the consolidated coordinate array pointer. */
  681.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  682.   
  683.   assert (pcoord_v->stats[0].type == PVFLOAT);
  684.   
  685.   /* If there is no vertex color information, draw without it. */
  686.   /* Otherwise, grab the color array. */
  687.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  688.     {
  689.       while (count > 0)
  690.         {
  691.           /* Save connectivity pointer. */
  692.           oconnect = connect;
  693.           
  694.           /* Draw the polygon. */
  695.           rm_bgnpolygon();
  696.           for (i = nvert; i > 0; i--) 
  697.             {
  698.               if ( (vertex = *(connect++)-1) == -1) 
  699.                 {
  700.                   connect += i-1;
  701.                   break;
  702.                 }
  703.               
  704.               rm_v3f(pcoord[vertex]);
  705.             }
  706.           rm_endpolygon();
  707.           
  708.           /* Start connectivity anew. */
  709.           connect = oconnect;
  710.           
  711.           /* Draw the outline of the polygon, with Z values */
  712.           rm_bgnclosedline();
  713.           for (i = nvert; i > 0; i--) 
  714.             {
  715.               if ( (vertex = *(connect++)-1) == -1)
  716.                 {
  717.                   connect += i-1;
  718.                   break;
  719.                 }
  720.               rm_linev3f(pcoord[vertex]); 
  721.             }
  722.           rm_endclosedline();
  723.           
  724.           count--;
  725.         }
  726.       
  727.     }
  728.   else 
  729.     {
  730.       /* Set pointers to the actual data and the size of the data */
  731.       /* sets. */
  732.       assert (vcolor_v->stats[0].type == PVINTEGER);
  733.       
  734.       /* There is color information.  Get it and use it to draw the */
  735.       /* appropriate shapes. */
  736.       vcolor = (int *) vcolor_v->data;
  737.  
  738.       while (count > 0) 
  739.         {
  740.           /* Save connectivity pointer. */
  741.           oconnect = connect;
  742.           
  743.           /* Draw the polygon. */
  744.           rm_bgnpolygon();
  745.           for (i = nvert; i > 0; i--) 
  746.             {
  747.               if ( (vertex = *(connect++)-1) == -1) 
  748.                 {
  749.                   connect += i-1;
  750.                   break;
  751.                 }
  752.               if (i == nvert)
  753.                 rm_palettecpack(vcolor[vertex]);
  754.               rm_v3f(pcoord[vertex]);
  755.             }
  756.           rm_endpolygon();
  757.           
  758.           /* Start connectivity anew. */
  759.           connect = oconnect;
  760.           
  761.           /* Draw the outline of the polygon, with Z values */
  762.           rm_bgnclosedline();
  763.           for (i = nvert; i > 0; i--) 
  764.             {
  765.               if ( (vertex = *(connect++)-1) == -1)
  766.                 {
  767.                   connect += i-1;
  768.                   break;
  769.                 }
  770.               rm_linev3f(pcoord[vertex]); 
  771.             }
  772.           rm_endclosedline();
  773.           
  774.           count--;
  775.         }
  776.       
  777.     }
  778.   
  779.   return ST_OKAY;
  780. }
  781.  
  782.  
  783.  
  784.  
  785.  
  786. /* Define FILENAME if you want output to a file. */
  787. #define PICXRES  pv->dv_width
  788. #define PICYRES  pv->dv_height
  789. #define CROPMINX 0.0
  790. #define CROPMAXX 1.0
  791. #define CROPMINY 0.0
  792. #define CROPMAXY 1.0
  793. #define CAMXPOS  win->cfrom[X]
  794. #define CAMYPOS  win->cfrom[Y]
  795. #define CAMZPOS  win->cfrom[Z]
  796. #define CAMXDIR  (win->at[X] - win->cfrom[X])
  797. #define CAMYDIR  (win->at[Y] - win->cfrom[Y])
  798. #define CAMZDIR  (win->at[Z] - win->cfrom[Z])
  799. #define CAMROLL  (RtFloat)((float)win->twist*0.1 + 90.0)
  800. #define CAMFOV   (RtFloat)((float)win->view_angle*0.1)
  801.  
  802. void dump_renderman (state_t *state, window_t *win, char *fname)
  803. {
  804.   polyview_t *pv;
  805.   object_t *obj;
  806.   int i;
  807.   RtPoint CameraFrom, CameraTo;
  808.   RtFloat fov;
  809.   FILE *save_stdout, *rmfp;
  810.  
  811. #if 0
  812.   rmfp = fopen (fname, "w");
  813.   if (rmfp == NULL)
  814.     {
  815.       stprintf (state, "Could not open RenderMan output file.");
  816.       return;
  817.     }
  818.   save_stdout = stdout;
  819.   stdout = rmfp;
  820. #endif
  821.  
  822.   CameraFrom[0] = CAMXPOS;
  823.   CameraFrom[1] = CAMYPOS;
  824.   CameraFrom[2] = CAMZPOS;
  825.  
  826.   CameraTo[0] = CAMXDIR;
  827.   CameraTo[1] = CAMYDIR;
  828.   CameraTo[2] = CAMZDIR;
  829.  
  830.   /* Should handle both orthographic and perspective! */
  831.   fov = CAMFOV;
  832.  
  833.   /* Load color array. */
  834.   for (i = 0; i < 256; i++)
  835.     {
  836.       rc[i][0] = (float)state->pal[i][0]/255.0;
  837.       rc[i][1] = (float)state->pal[i][1]/255.0;
  838.       rc[i][2] = (float)state->pal[i][2]/255.0;
  839.     }
  840.  
  841.   assert (win->type == POLYVIEW);
  842.   pv = (polyview_t *)WIN_IMAGE(win);
  843.  
  844.   if (WIN_FRAME(win) == NULL)
  845.     return;
  846.   
  847.   obj = FRA_ROOTOBJ (WIN_FRAME(win));
  848.   
  849.   /* Make sure that the object exists, has information associated */
  850.   /* with it, and has a drawing function. */
  851.   assert (obj != NULL);
  852.   assert (obj->info != NULL);
  853.   assert (obj->info->draw_fn != NULL);
  854.   
  855.   /* RenderMan. */
  856.   RiBegin(fname); /* As always */
  857.   {
  858. #ifdef FILENAME
  859.     RiDisplay(FILENAME, RI_FILE, RI_RGBA, RI_NULL); 
  860. #else
  861.     RiDisplay("RenderMan", RI_FRAMEBUFFER, RI_RGB, RI_NULL);
  862. #endif
  863.     
  864.     RiFormat((RtInt) PICXRES, (RtInt) PICYRES, 1.0);
  865.     
  866.     /* Low shading rate.  Doesn't seem to matter for polygon
  867.        rendering, but it does for spheres/cylinders/etc. */
  868.     RiShadingRate(16.0);
  869.     
  870.     RiCropWindow(CROPMINX, CROPMAXX, CROPMINY, CROPMAXY);
  871.  
  872.     /* This should probably go if we go back to the PlaceCamera
  873.        shit. */
  874.     RiOrientation (RI_RH);
  875.     RiSides (2);
  876.     
  877.     RiProjection ("perspective", RI_FOV, (RtPointer)&fov, RI_NULL);
  878.     RiFrameAspectRatio ((RtFloat)((float)PICXRES/(float)PICYRES));
  879.  
  880.     /*
  881.       G. Bourhis (august 93) : replace call to :
  882.     PlaceCamera(CameraFrom, CameraTo, CAMROLL);
  883.     by calls equivalent to the ones in redraw_polyview() for GL. */
  884.     RiIdentity();
  885.     RiScale(1.,1.,-1.);        /* this one is not in redraw_polyview(),*/
  886.                 /* I add it because Ri is right handed. */
  887.     RiRotate(WIN_TWIST(win), 0.0, 0.0, 1.0);
  888.     RiRotate(90.0-WIN_SFROM(win)[PHI]*180.0/PI, 1., 0., 0.);
  889.     RiRotate(-90.0-WIN_SFROM(win)[THETA]*180.0/PI, 0., 1., 0.);
  890.     RiRotate(-90.0, 1., 0., 0.);
  891.     RiTranslate(-CAMXPOS, -CAMYPOS, -CAMZPOS);
  892.     
  893.     RiWorldBegin();
  894.     {
  895.       if (WIN_DRAW(win) == draw_faces)
  896.         rm_draw_faces (state, win, obj, obj->info);
  897.       if (WIN_DRAW(win) == draw_edges)
  898.         rm_draw_edges (state, win, obj, obj->info);
  899.       if (WIN_DRAW(win) == draw_outlined_faces || WIN_DRAW(win) == DrawTrans ||
  900.           WIN_DRAW(win) == draw_hidden_edges)
  901.         rm_draw_outlined_faces (state, win, obj, obj->info);
  902.       if (WIN_DRAW(win) == draw_vertices)
  903.         rm_draw_vertices (state, win, obj, obj->info);
  904.     }
  905.     RiWorldEnd();
  906.   }
  907.   RiEnd();
  908.   
  909. #if 0
  910.   /* Finish up the rib file. */
  911.   fflush (rmfp);
  912.   fclose (rmfp);
  913.   
  914.   /* Restore stdout. */
  915.   stdout = save_stdout;
  916. #endif
  917.   
  918.   return;
  919. }
  920.  
  921. #endif /* DIRECT_RENDERMAN */
  922.  
  923.  
  924.  
  925.  
  926.  
  927. /* ------------------------------------------------------------------------ */
  928. /* ------------------------- DUMP_CFILE routines -------------------------- */
  929. /* ------------------------------------------------------------------------ */
  930.  
  931. #ifdef DUMP_CFILE
  932.  
  933. /* ------------------------------------------------------------------------ */
  934. /* ---------------------- RENDERMAN OUTPUT ROUTINES ----------------------- */
  935. /* ------------------------------------------------------------------------ */
  936.  
  937. static FILE *rmfp = NULL;
  938.  
  939.  
  940. static int rm_draw_vertices (state_t *state, window_t *win, object_t *obj, 
  941.                            objinfo_t *info)
  942. {
  943.   return 0;
  944. }
  945.  
  946.  
  947. static int rm_draw_edges (state_t *state, window_t *win, object_t *obj, 
  948.                            objinfo_t *info)
  949. {
  950.   return 0;
  951. }
  952.  
  953.  
  954. /* ------------------------------------------------------------------------ */
  955. /* ------------------------------------------------------------------------ */
  956. /* ------------------------------------------------------------------------ */
  957.  
  958. static int num_vertices = 0;
  959.  
  960. static void rm_bgnpolygon (void)
  961. {
  962.   num_vertices = 0;
  963.   return;
  964. }
  965.  
  966. static void rm_v3f (float *vv)
  967. {
  968.   /* Copy the vertex. */
  969.   fprintf (rmfp, "  rp[%d][0] = %f;\n", num_vertices, vv[0]);
  970.   fprintf (rmfp, "  rp[%d][1] = %f;\n", num_vertices, vv[1]);
  971.   fprintf (rmfp, "  rp[%d][2] = %f;\n", num_vertices, vv[2]);
  972.  
  973.   /* Increment the count. */
  974.   num_vertices++;
  975.  
  976.   /* Sanity check. */
  977.   if (num_vertices > 4)
  978.     {
  979.       fprintf (stderr, "Uh oh, boss, we've got more than 4 vertices here...\n");
  980.       abort ();
  981.     }
  982.   return;
  983. }
  984.  
  985. static void rm_endpolygon (void)
  986. {
  987.   fprintf (rmfp, "  RiPolygon( (RtInt)%d, RI_P, (RtPointer)rp, RI_NULL );\n\n",
  988.            num_vertices);
  989.   return;
  990. }
  991.  
  992. static void rm_palettecpack (int c)
  993. {
  994.   fprintf (rmfp, "  RiColor(rc[%d]);\n", c);
  995. }
  996.  
  997.  
  998.  
  999. static int rm_draw_faces (state_t *state, window_t *win, object_t *obj, 
  1000.                           objinfo_t *info)
  1001. {
  1002.   long count;
  1003.   Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
  1004.   float    (*pcoord)[DIMS];
  1005.   int *vcolor, *connect;
  1006.   char *picked;
  1007.   int i, nvert, vertex, single_color;
  1008.   
  1009.   /* Get pointers to the pertinent data sets */
  1010.   vdata = obj->u.obj.vdata;
  1011.   vcolor_v = get_vdata(state, vdata[VCOLOR]);
  1012.   if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
  1013.     if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
  1014.       return rm_draw_vertices(state, win, obj, info);
  1015.   
  1016.   /* If the plist does not describe polygons, draw edges. */
  1017.   if (connect_v->stats[0].rec_size < 3)
  1018.     return rm_draw_edges(state, win, obj, info);
  1019.   
  1020.   if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
  1021.     return ST_OKAY;
  1022.   
  1023.   /* Collect connectivity information for drawing. */
  1024.   connect = (int *) connect_v->data;
  1025.   count = connect_v->stats[0].rec_count;
  1026.   nvert = connect_v->stats[0].rec_size;
  1027.   
  1028.   /* Set up the consolidated coordinate array pointer. */
  1029.   pcoord = (float (*)[DIMS]) pcoord_v->data;
  1030.   assert (pcoord_v->stats[0].type == PVFLOAT);
  1031.   
  1032.   /* If there is no vertex color information, draw without it */
  1033.   /* (use the FOREGROUND color).  Otherwise, grab the color array. */
  1034.   if (vcolor_v == NULL || vcolor_v->data == NULL) 
  1035.     {
  1036.       while (count > 0) 
  1037.         {
  1038.           rm_bgnpolygon();
  1039.           for (i = nvert; i > 0; i--) 
  1040.             {
  1041.               if ( (vertex = *(connect++)-1) == -1) 
  1042.                 {
  1043.                   connect += i-1;
  1044.                   break;
  1045.                 }
  1046.               rm_v3f(pcoord[vertex]);
  1047.             }
  1048.           rm_endpolygon();
  1049.           
  1050.           count--;
  1051.         }
  1052.     }
  1053.   else 
  1054.     {
  1055.       /* Set pointers to the actual data and the size of the data */
  1056.       /* sets. */
  1057.       assert (vcolor_v->stats[0].type == PVINTEGER);
  1058.       
  1059.       /* There is color information.  Get it and use it to draw the */
  1060.       /* appropriate shapes. */
  1061.       vcolor = (int *) vcolor_v->data;
  1062.  
  1063.       while (count > 0) 
  1064.         {
  1065.           rm_bgnpolygon();
  1066.           for (i = nvert; i > 0; i--) 
  1067.             {
  1068.               if ((vertex = *(connect++)-1) == -1) 
  1069.                 {
  1070.                   connect += i-1;
  1071.                   break;
  1072.                 }
  1073.               
  1074.               if (i == nvert)
  1075.                 rm_palettecpack (vcolor[vertex]);
  1076.  
  1077.               rm_v3f(pcoord[vertex]);
  1078.             }
  1079.           rm_endpolygon();
  1080.           
  1081.           count--;
  1082.         }
  1083.     }
  1084.   
  1085.   return ST_OKAY;
  1086. }
  1087.  
  1088.  
  1089.  
  1090.  
  1091. void dump_renderman (state_t *state, window_t *win, char *fname)
  1092. {
  1093.   polyview_t *pv;
  1094.   object_t *obj;
  1095.   int i;
  1096.  
  1097.   assert (win->type == POLYVIEW);
  1098.   pv = (polyview_t *)WIN_IMAGE(win);
  1099.  
  1100.   rmfp = fopen (fname, "w");
  1101.   if (rmfp == NULL)
  1102.     {
  1103.       stprintf (state, "Could not open output file.");
  1104.       return;
  1105.     }
  1106.  
  1107.   fprintf (rmfp, "/* NCSA Polyview 3.0 Renderman output file. */\n\n");
  1108.   fprintf (rmfp, "/* National Center for Supercomputing Applications */\n");
  1109.   fprintf (rmfp, "/* University of Illinois at Urbana-Champaign */\n");
  1110.   fprintf (rmfp, "/* polyview@ncsa.uiuc.edu */\n\n");
  1111.  
  1112.   fprintf (rmfp, "#include <ri.h>\n\n");
  1113.  
  1114.   fprintf (rmfp, "/* Define FILENAME if you want output to a file. */\n\n");
  1115.   fprintf (rmfp, "#define PICXRES %d\n", pv->dv_width);
  1116.   fprintf (rmfp, "#define PICYRES %d\n\n", pv->dv_height);
  1117.   fprintf (rmfp, "#define CROPMINX 0.0\n");
  1118.   fprintf (rmfp, "#define CROPMAXX 1.0\n");
  1119.   fprintf (rmfp, "#define CROPMINY 0.0\n");
  1120.   fprintf (rmfp, "#define CROPMAXY 1.0\n\n");
  1121.   fprintf (rmfp, "#define CAMXPOS %f\n", win->cfrom[X]);
  1122.   fprintf (rmfp, "#define CAMYPOS %f\n", win->cfrom[Y]);
  1123.   fprintf (rmfp, "#define CAMZPOS %f\n\n", win->cfrom[Z]);
  1124.   fprintf (rmfp, "#define CAMXDIR %f\n", win->at[X] - win->cfrom[X]);
  1125.   fprintf (rmfp, "#define CAMYDIR %f\n", win->at[Y] - win->cfrom[Y]);
  1126.   fprintf (rmfp, "#define CAMZDIR %f\n\n", win->at[Z] - win->cfrom[Z]);
  1127.   /* ??? */
  1128.   fprintf (rmfp, "#define CAMROLL 0.0\n\n");
  1129.   /* ??? */
  1130.   fprintf (rmfp, "#define CAMZOOM 4.5\n\n");
  1131.  
  1132.   fprintf (rmfp, "RtPoint CameraFrom   = { CAMXPOS, CAMYPOS, CAMZPOS},\n");
  1133.   fprintf (rmfp, "        CameraTo     = { CAMXDIR, CAMYDIR, CAMZDIR};\n\n");
  1134.  
  1135.   fprintf (rmfp, "main()\n");
  1136.   fprintf (rmfp, "{\n");
  1137.   fprintf (rmfp, "    RiBegin(RI_NULL); /* As always */\n\n");
  1138.  
  1139.   fprintf (rmfp, "        /* Output image characteristics */\n");
  1140.   fprintf (rmfp, "#ifdef FILENAME\n");
  1141.   fprintf (rmfp, "       /* output to given file */\n");
  1142.   fprintf (rmfp, "        RiDisplay(FILENAME, RI_FILE, RI_RGBA, RI_NULL); \n");
  1143.   fprintf (rmfp, "#else\n");
  1144.   fprintf (rmfp, "        RiDisplay(\"RenderMan\", RI_FRAMEBUFFER, RI_RGB, RI_NULL);\n");
  1145.   fprintf (rmfp, "#endif\n");
  1146.   fprintf (rmfp, "        RiFormat((RtInt) PICXRES, (RtInt) PICYRES, 1.0); /* image resolution */\n");
  1147.   fprintf (rmfp, "        RiShadingRate(1.0);           /* Good quality, use 0.25 for better. */\n");
  1148.   fprintf (rmfp, "        /* region of image rendered */\n");
  1149.   fprintf (rmfp, "        RiCropWindow(CROPMINX, CROPMAXX, CROPMINY, CROPMAXY);\n\n");
  1150.  
  1151.   fprintf (rmfp, "        /* Nature of the projection to the image plane */\n");
  1152.   fprintf (rmfp, "        RiProjection(\"perspective\", RI_NULL);    /* perspective view */\n\n");
  1153.  
  1154.   fprintf (rmfp, "        /* Camera characteristics */\n");
  1155.   fprintf (rmfp, "        FrameCamera((float)PICXRES*CAMZOOM, (float)PICXRES, (float)PICYRES);\n\n");
  1156.         
  1157.   fprintf (rmfp, "        /* Camera position and orientation */\n");
  1158.   fprintf (rmfp, "        CameraTo[0] -= CameraFrom[0];\n");
  1159.   fprintf (rmfp, "        CameraTo[1] -= CameraFrom[1];\n");
  1160.   fprintf (rmfp, "        CameraTo[2] -= CameraFrom[2];\n");
  1161.   fprintf (rmfp, "        PlaceCamera(CameraFrom, CameraTo, CAMROLL);\n\n");
  1162.  
  1163.   fprintf (rmfp, "        /* Now describe the world */\n");
  1164.   fprintf (rmfp, "        RiWorldBegin();\n");
  1165.   fprintf (rmfp, "            Go();\n");
  1166.   fprintf (rmfp, "        RiWorldEnd();\n\n");
  1167.         
  1168.   fprintf (rmfp, "    RiEnd();\n\n");
  1169.  
  1170.   fprintf (rmfp, "    return 0;\n");
  1171.   fprintf (rmfp, "}\n\n\n");
  1172.  
  1173.   fprintf (rmfp, "RtColor rc[256] = {\n");
  1174.   for (i = 0; i < 256; i++)
  1175.     {
  1176.       fprintf (rmfp, "  { %f, %f, %f },\n", (float)state->pal[i][0]/255.0, 
  1177.                (float)state->pal[i][1]/255.0, (float)state->pal[i][2]/255.0);
  1178.     }
  1179.   fprintf (rmfp, "};\n\n");
  1180.  
  1181.   fprintf (rmfp, "Go() {\n");
  1182.   fprintf (rmfp, "  RtPoint rp[4];\n\n");
  1183.  
  1184.   if (WIN_FRAME(win) == NULL)
  1185.     return;
  1186.  
  1187.   obj = FRA_ROOTOBJ (WIN_FRAME(win));
  1188.  
  1189.   /* Make sure that the object exists, has information associated */
  1190.   /* with it, and has a drawing function. */
  1191.   assert (obj != NULL);
  1192.   assert (obj->info != NULL);
  1193.   assert (obj->info->draw_fn != NULL);
  1194.  
  1195.   /* Load default color, in case none are being used. */
  1196.   fprintf (rmfp, "  rc[0] = %f;\n", 0.8);
  1197.   fprintf (rmfp, "  rc[1] = %f;\n", 0.8);
  1198.   fprintf (rmfp, "  rc[2] = %f;\n", 0.8);
  1199.   fprintf (rmfp, "  RiColor(rc);\n\n");
  1200.   
  1201.   rm_draw_faces (state, win, obj, obj->info);
  1202.   
  1203.   fprintf (rmfp, "}\n\n");
  1204.   
  1205.   fflush (rmfp);
  1206.   fclose (rmfp);
  1207.  
  1208.   rmfp = NULL;
  1209.  
  1210.   return;
  1211. }
  1212.  
  1213. #endif /* DUMP_CFILE */
  1214.  
  1215. #endif /* RENDERMAN */
  1216.  
  1217. /* DO NOT PUT CODE HERE! */
  1218.